package com.colabo.j2ee.web.core.log;

import java.io.Serializable;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.colabo.j2ee.web.core.common.CommonConstants;
import com.colabo.j2ee.web.core.util.PropertyUtil;

/**
 * 用于对一个java类的全天候环境的拦截，以便记入日志
 * 环绕的拦截是功能强大的，但同时也是有性能代价的，因此，建议能用不同的before和after等实现的，就不要用环绕机制<br>
 * 使用方法：<br>
 * 1：首先在xml配置文件中声明advise <bean id="logaround" class="com.cib.cap.base.common.log.LogAroundAdvice"/>
 * 2:然后在xml配置文件中设置拦截的模式 <br>
 * &lt;aop:config &gt; &lt;aop:pointcut id="serviceOperation" expression="execution(*com.cib.cap..*ServiceImpl.*(..))"/&gt;<br>
 * 		&lt;aop:advisor pointcut-ref="serviceOperation" advice-ref="logaround" /&gt;<br>
 * &lt;/aop:config&gt; <br>
 * 3:采用advisor方式，可以让log拦截和其它拦截器一起工作而互相不受干扰<br>
 */
public class LogAroundAdvice implements MethodInterceptor, Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	protected final Log logger = LogFactory.getLog(LogAroundAdvice.class);
	public Object invoke(MethodInvocation invocation) throws Throwable {
		// 调用之前可以做一些处理
		long procTime = System.currentTimeMillis();
		// 解析参数
		Object[] args = invocation.getArguments();
		StringBuffer sb = new StringBuffer("");
		if (args != null) {
			for (int i = 0; i < args.length; i++) {
				if (args[i] != null) {
					sb.append(args[i].toString());
					sb.append(",");
				}
			}
		} else {
			sb.append("无输入参数");
		}

		logger.info(PropertyUtil.getPropertyByKey(CommonConstants.MSG_LOG_BEFORE, new String[] {
				invocation.getClass().getName(), invocation.getMethod().getName(), sb.toString() }));
		Object returnObject = null;

		try {
			// 调用目标方法,返回结果要转为Serializable，否则远程调用就异常了,调用之后还可以做一些处理
			returnObject = (Serializable) invocation.proceed();
			return returnObject;
		} finally {
			// 计算执行时间
			procTime = System.currentTimeMillis() - procTime;
			logger.info(PropertyUtil.getPropertyByKey(CommonConstants.MSG_LOG_AFTER, new String[] {
					invocation.getClass().getName(), invocation.getMethod().getName(),
					returnObject != null ? returnObject.toString() : "无返回值" }));
			logger.info(PropertyUtil.getPropertyByKey(CommonConstants.MSG_LOG_AFTER, new String[] {
					invocation.getClass().getName(), invocation.getMethod().getName(), String.valueOf(procTime) }));
		}
	}
}
